package net.galacticwar.replayserver.admin;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import net.galacticwar.replayserver.ServerManagerMBean;

public class AdminTools implements LoginCallback {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(AdminTools.class.getName());

	public static final String VERSION = "1.0";
	
	private LoginFrame loginFrame;
	private PropertyController propertyController;
	
	private JMXConnector jmxc;
	
	private ServerManagerMBean mbeanProxy;
	

	

	public AdminTools() {
		showLoginFrame();
	}
	
	
	private void showLoginFrame(){
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				loginFrame = new LoginFrame();
				loginFrame.setLoginCallback(AdminTools.this);
				loginFrame.setLocationRelativeTo(null);
				loginFrame.setVisible(true);
			}
		});
	}
	
	private void closeLoginFrame(){
		loginFrame.dispose();
	}
	
	private void showPropertyFrame() {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				
				propertyController.show();
			

			}
		});
	}
	
	@Override
	public void connect(String hostname, int port, String loginName,
			char[] password) {

//		System.setProperty("com.sun.management.jmxremote.ssl.need.client.auth", "true");
//	    System.setProperty("javax.net.ssl.keyStore", "test.cert");
//	    System.setProperty("javax.net.ssl.keyStorePassword", "pass");
//	    System.setProperty("javax.net.ssl.trustStore", "test.cert");
//	    System.setProperty("javax.net.ssl.trustStorePassword", "pass");

	    
//		RMIServerSocketFactory ssf = new SslRMIServerSocketFactory();
//		RMIClientSocketFactory csf = new SslRMIClientSocketFactory();
		

		String[] credentials = new String[2];
		// The user will travel as clear text

		credentials[0] = loginName;
		credentials[1] = new String(password);

		Map<String,Object> env = new HashMap<String,Object>();
		env.put(JMXConnector.CREDENTIALS, credentials);

//		env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory());

		// Create an RMI connector client and connect it to
		// the RMI connector server
		String urlPath = "/jndi/rmi://" + hostname + ":" + port + "/jmxrmi";
     
		try {
			
			JMXServiceURL url = new JMXServiceURL("rmi", "", 0, urlPath);
			jmxc = JMXConnectorFactory.connect(url, env);

			createProxies();
			propertyController = new PropertyController(AdminTools.this, mbeanProxy);
			
			closeLoginFrame();
			showPropertyFrame();
			
		} catch (MalformedURLException e) {
			// should not reach here
		} catch (IOException e) {
			System.err.println("\nCommunication error: " + e.getMessage());
			JOptionPane.showMessageDialog(loginFrame, "Impossible de se connecter");
		}
		catch (SecurityException e) {
			System.err.println("\nCommunication error: " + e.getMessage());
			JOptionPane.showMessageDialog(loginFrame, "Impossible de se connecter");
		}
	}
	
	private void createProxies() {
		try {
			ObjectName mbeanName = new ObjectName("net.galacticwar.replayserver.ReplayServer:type=ServerManager");
			mbeanProxy = JMX.newMBeanProxy(getServer(),
					mbeanName, ServerManagerMBean.class, true);

		} catch (MalformedObjectNameException e) {
			e.printStackTrace();
		} catch (NullPointerException e) {
			e.printStackTrace();
		}


	}
	
	@Override
	public void disconnect() {
		try {
			if (jmxc!=null && jmxc.getMBeanServerConnection()!=null) {
				jmxc.close();
			}
		} catch (IOException e) {
		}
		System.exit(0);
		
	}
	
	@Override
	public MBeanServerConnection getServer() {
		try {
			return jmxc.getMBeanServerConnection();
		} catch (IOException e) {
			logger.logp(Level.SEVERE, "AdminTools", "getServer()", "", e); 
			
			return null;
		}
	}
	

	
	public static void main(String[] args) throws Exception {
		new AdminTools();
	}

}
